package net.alche.fa.core;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.swing.Renderer;

import net.alche.al.util.AC;
import net.alche.fa.core.model.FaValue;
import net.alche.fa.core.parse.FaKeyWord;

@SuppressWarnings("all")
public class FaUtil {
  public static List<FaValue> pars(Object... objs) {
    List<FaValue> params = new ArrayList<>();
    if (objs != null && objs.length > 0) {
      for (Object obj : objs) {
        params.add(new FaValue(obj));
      }
    }
    return params;
  }

  public static CodeLevel newCodeLvl() {
    CodeLevel lvl = new CodeLevel();
    lvl.uuid = "uuid";
    lvl.postCode = "000";
    lvl.debugUserId = "0";
    return lvl;
  }

  public static FaValue mapToPojo(FaPlatform plat, String pojoName, Map<String, Object> map) {
    if ("Map".equals(pojoName)) {
      return new FaValue(map);
    } else if ("String".equals(pojoName) || "Integer".equals(pojoName) || "Double".equals(pojoName)) {
      FaValue fv = null;
      for (String key : map.keySet()) {
        fv = new FaValue(map.get(key));
      }
      return fv;
    } else {
      try {
        FaClass fac = plat.instance(pojoName, null);
        return mapToPojo(fac.getThisSage(), map);
      } catch (FaException e) {
        e.printStackTrace();
        return new FaValue();
      }
    }
  }

  public static FaValue mapToPojo(SageStone st, Map<String, Object> map) {
    FaValue fav = new FaValue(st);
    if (map != null && !map.isEmpty()) {
      for (Entry<String, Object> en : map.entrySet()) {
        String attrName = AC.str.getHump(en.getKey());
        if (st.getVars().get(attrName) == null) {
          continue;
        }
        FaValue varVal = st.getVars().get(attrName);
        if (en.getValue() instanceof Map) {
          FaValue faValue = FaUtil.mapToPojo(st.getPlat(), varVal.getObjType(), (Map) en.getValue());
          st.putVar(attrName, faValue);
        } else {
          st.putVar(attrName, new FaValue(en.getValue(), varVal.type));
        }
      }
    } else {
      fav.setNull(true);
    }
    return fav;
  }

  public static FaValue mapToPojoDeep(SageStone st, Map<String, Object> map) {
    FaValue fav = new FaValue(st);
    if (map != null && !map.isEmpty()) {
      for (Entry<String, Object> en : map.entrySet()) {
        String attrName = AC.str.getHump(en.getKey());
        if (st.getVars().get(attrName) == null) {
          continue;
        }
        FaValue varVal = st.getVars().get(attrName);
        if (varVal == null) {
          continue;
        }
        if (en.getValue() instanceof Map) {
          FaValue faValue = FaUtil.mapToPojoDeep(st.getPlat(), varVal.getObjType(), (Map) en.getValue());
          st.putVar(attrName, faValue);
        } else if (en.getValue() instanceof List) {
          List list = (List) en.getValue();
          String objType = varVal.getObjType();
          String pojoName = objType.substring(5, objType.length() - 1);
          boolean isSimpleType = FaKeyWord.isBaseDataType(pojoName);
          List toList = new ArrayList();
          FaPlatform plat = st.getPlat();
          Boolean isMap = null;
          for (Object obj : list) {
            if (isMap == null) {
              isMap = obj instanceof Map;
            }
            if (isMap) {
              Map toMap = (Map) obj;
              SageStone toSage = null;
              try {
                FaClassConf fconf = plat.getClassConf(pojoName);
                FaClass fac = fconf.instance(null);
                toSage = fac.getThisSage();
              } catch (FaException e) {
                e.printStackTrace();
              }
              if (toSage != null) {
                toList.add(mapToPojoDeep(toSage, toMap));
              }
            } else {
              toList.add(new FaValue(obj, FaValue.getChar(pojoName)));
            }
          }
          st.putVar(attrName, new FaValue(toList, varVal.type));
        } else {
          st.putVar(attrName, new FaValue(en.getValue(), varVal.type));
        }
      }
    } else {
      fav.setNull(true);
    }
    return fav;
  }

  public static FaValue mapToPojoDeep(FaPlatform plat, String pojoName, Map<String, Object> map) {
    if ("Map".equals(pojoName)) {
      return new FaValue(map);
    } else {
      try {
        FaClass fac = plat.instance(pojoName, null);
        return mapToPojoDeep(fac.getThisSage(), map);
      } catch (FaException e) {
        e.printStackTrace();
        return new FaValue();
      }
    }
  }
}
